﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OrganizationName.DynamicData
{
    public class Data : _ID
    {
        public Schema Schema { get; set; }
        public string Value { get; set; }
        public Blob Blob { get; set; }

        public Data CreateChild(string value)
        {
            Data child = new Data();
            child.Parent = this;
            child.Value = value;

            Children.Add(child);

            return child;
        }

        public static Data FromXml(string name, string schemaName, string xmlPath)
        {
            System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument();
            xmlDocument.Load(xmlPath);

            Schema dataSchema = Schema.FromXml(schemaName, xmlPath);
            Data data = new Data();
            data.Value = name;
            data.Schema = dataSchema;

            FillData(data, xmlDocument);

            return data;
        }

        public static Data FromXml(string name, Schema dataSchema, string xmlPath)
        {
            System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument();
            xmlDocument.Load(xmlPath);

            Data data = new Data();
            data.Value = name;
            data.Schema = dataSchema;

            FillData(data, xmlDocument);

            return data;
        }

        private static void FillData(Data data, System.Xml.XmlNode node)
        {
            if (data.Schema.Children != null)
            {
                foreach (Schema childSchema in data.Schema.Children)
                {
                    if (childSchema.Type == 1)
                    {
                        System.Xml.XmlNodeList childNodes = node.SelectNodes(childSchema.Name);
                        foreach (System.Xml.XmlElement childNode in childNodes)
                        {
                            string dataValue = null;
                            if (childNode.ChildNodes != null && childNode.ChildNodes.Count > 0)
                            {
                                if (childNode.ChildNodes[0] is System.Xml.XmlText || childNode.ChildNodes[0] is System.Xml.XmlCDataSection)
                                {
                                    dataValue = childNode.ChildNodes[0].InnerText;
                                }
                            }
                            Data childData = data.CreateChild(dataValue);
                            childData.Schema = childSchema;
                            FillData(childData, childNode);
                        }
                    }
                    else if (childSchema.Type == 2)
                    {
                        if (node.Attributes != null)
                        {
                            System.Xml.XmlAttribute childAttribute = node.Attributes[childSchema.Name];
                            if (childAttribute != null)
                            {
                                Data childData = data.CreateChild(childAttribute.Value);
                                childData.Schema = childSchema;
                            }
                        }
                    }
                }
            }
        }

        public override string ToString()
        {
            return (Schema != null ? Schema.ToString() : "Value = ") + " (" + Value + ")";
        }

        protected override string InsertScriptFieldList
        {
            get { return "[Schema], [Value], [Blob]"; }
        }

        protected override string InsertScriptValueList
        {
            get { return (Schema != null ? Schema.InsertID : "0") + ", '" + (Value != null ? Value.Replace("'", "''") : "") + "', " + (Blob != null ? Blob.InsertID : "0"); }
        }

        public override void GenerateInsertScript(StringBuilder insertScriptBuilder)
        {
            if (this == Root)
            {
                Schema.GenerateInsertScript(insertScriptBuilder);
            }
            base.GenerateInsertScript(insertScriptBuilder);
        }
    }
}
